package org.bud.util.bit;

import org.bud.excel.expot.exception.UtilException;
import org.bud.util.constant.Constant;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author shaun
 * @date 2024/7/18
 * @instruction
 */
public abstract class Objects {
    public static <T> void setValue(Object obj,String key,T value){
        setValue(obj,key,value,true);
    }

    public static <T> void setValue(Object obj,String key,T value,boolean setNull){
        if(obj == null){
            return;
        }
        if(obj instanceof Map){
            ((Map<String,Object>) obj).put(key,value);
            return;
        }
        try{
            String name = setter(key);
            if(value != null){
                obj.getClass().getMethod(name,value.getClass()).invoke(obj,value);
                return;
            }
            if(!setNull){
                return;
            }
            getMethod(obj.getClass(),name).invoke(obj,null);
        } catch (Exception e){
            throw new UtilException(e);
        }
    }

    public static Object getValue(Object obj,String key){
        if(obj == null){
            return null;
        }
        if(obj instanceof Map){
            return ((Map<String,Object>) obj).get(key);
        }
        try{
            String name = getter(key);

            return obj.getClass().getMethod(name).invoke(obj);

        } catch (Exception e){
            throw new UtilException(e);
        }
    }

    public static <C> Method getMethod(Class<C> clazz,String name){
        return getMethod(clazz,Object.class,name);
    }

    public static <C,P> Method getMethod(Class<C> clazz,Class<P> stopClazz,String name){
        Method method = null;
        if(method != null || clazz.equals(stopClazz)){
            return method;
        }
        for(Method md : clazz.getDeclaredMethods()){
            if(md.getName().equals(name)){
                return md;
            }
        }
        return getMethod(clazz.getSuperclass(),stopClazz,name);
    }

    private static String getter(String key){
        return Constant.GETTER_METHOD_PREFIX + Strings.capitalize(key);
    }

    private static String setter(String key){
        return Constant.SETTER_METHOD_PREFIX + Strings.capitalize(key);
    }
}
